const MYSQL = require("../../sql/mysql");
const Dayjs = require("dayjs");

// 将我的代码全部注释，方便查看

// 漂流瓶表
const sql_drift_name = "drift";
// 用户漂流瓶记录表
const sql_user_drift_log_name = "drift_log";
/**
 * 漂流瓶运维情况
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function GetDriftObserver() {
  try {
    // 今日漂流瓶数量
    // 今日被获取数量
    // 本月被获取数量
    // 今日发布数量
    // 漂流瓶总数
    // 漂流瓶获取总数
    // 本月新增漂流瓶
    // 本月被获取数量

    // 获取Mysql连接
    const Conline = await MYSQL.promise().getConnection();
    // 今日漂流瓶数量



  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "发布失败" };
    }
  }
}

/**
 * 获取漂流瓶
 * @return {promise<{code:string,msg:string}>}
 */
async function GetDrift(Request) {
  try {
    let user = Request.$user;
    let super_admin = Request.$super_admin;
    // 当前时间时间戳
    let date_now = Request.$requestTime;
    // 漂流瓶数据地址
    let DriftListRedisPath = `${ProjectName}:Drift:List`;
    // 用户今日漂流瓶获取次数
    let userDriftToDayCountRedisPath = `${ProjectName}:user:${user}:Drift:TodayCount`;
    // 用户今日漂流瓶获取总数
    let userDriftTotalCountRedisPath = `${ProjectName}:user:${user}:Drift:TotalCount`;
    // 用户漂流瓶获取记录Redis地址
    let userRecordGetterRedisPath = `${ProjectName}:user:${user}:Drift:RecordGetter`;
    // 用户漂流瓶发布记录
    let userPublishRedisPath = `${ProjectName}:user:${user}:Drift:Publish`;

    // 用户未读的漂流瓶记录
    let userDriftUnreadFlagRedisPath = `${ProjectName}:user:${user}:Drift:unreadFlag`;

    // 获取今日用户漂流瓶次数
    let GetUserTodayCount = await Redis.get(userDriftToDayCountRedisPath);

    if (!super_admin && GetUserTodayCount >= 10) {
      return {
        code: 500,
        msg: "今日获取漂流瓶次数已达上限",
      };
    }
    // 生成Redis管道,并将下列代码一次提交到Redis
    const RedisPipeline = Redis.pipeline();

    if (!GetUserTodayCount) {
      // 计算今天剩余的秒数
      let NowDate = DayJs();
      let ToDaySeconds = NowDate.diff();
      // 设置初始值
      RedisPipeline.set(userDriftToDayCountRedisPath, 1);
      // 设置过期时间
      RedisPipeline.expire(userDriftToDayCountRedisPath, 8600);
    }

    // 计算用户差集
    await Redis.zdiffstore(userDriftUnreadFlagRedisPath, 3, [
      DriftListRedisPath,
      userPublishRedisPath,
      userRecordGetterRedisPath,
    ]);
    // 在未读的漂流瓶列表中，获取用户未读的漂流瓶
    let randomDrift = await Redis.zpopmin(userDriftUnreadFlagRedisPath);

    let drift_id = null;

    if (!randomDrift || !randomDrift?.length) {
      throw {
        code: 500,
        msg: "服务繁忙",
      };
    } else {
      drift_id = randomDrift[0];
    }

    // 漂流瓶信息地址
    let DriftInfoRedisPath = `${ProjectName}:Drift:Info:${drift_id}`;
    // 漂流瓶信息
    let driftInfo = await Redis.hgetall(DriftInfoRedisPath);
    let author = driftInfo.user;
    let value = driftInfo.value;
    // 用户信息地址
    let authorInfoRedisPath = `${ProjectName}:user:${author}:BaseInfo`;
    let authorInfo = await Redis.hgetall(authorInfoRedisPath);
    let { id, avatar, gender, nickname, username, state } = authorInfo;
    let userInfo = {
      id,
      avatar,
      gender,
      nickname,
      username,
      state,
    };

    // 添加该漂流瓶到用户获取记录
    RedisPipeline.zadd(userRecordGetterRedisPath, [date_now, drift_id]);
    // 添加一次获取次数到用户总数
    RedisPipeline.incr(userDriftTotalCountRedisPath);
    // 添加用户今日获取次数
    RedisPipeline.incr(userDriftToDayCountRedisPath);

    await RedisPipeline.exec();

    return {
      code: 0,
      msg: "操作成功",
      data: {
        data: {
          value,
          userInfo,
        },
      },
    };
  } catch (error) {
    throw error;
  }
}


/**
 * 删除漂流瓶
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function DeleteDrift(Request = {}, Params = {}) {
  try {
    let Body = Request.body;
    let user = Request.$user;
    let { operate_user } = Params
    let { id } = Body
    if (!id) {
      throw { code: 500, msg: "删除失败,id不能为空" };
    }
    let Where = null
    if (operate_user) {
      Where = `id = ${id} AND user = ${operate_user}`
    } else {
      Where = `id = ${id}`
    }
    // 获取Mysql连接
    const Conline = await MYSQL.promise().getConnection();
    // 更新数据
    let [UpdateResult] = await Conline.query(
      `UPDATE ${sql_drift_name} SET?
      WHERE ${Where}
      `,
      { state: 0 }
    );
    let { affectedRows } = UpdateResult
    if (affectedRows) {
      return {
        code: 0,
        msg: "删除成功",
      };
    } else {
      throw { code: 500, msg: "删除失败,记录不存在" };
    }
  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "操作失败" };
    }
  }
}

/**
 * 修改漂流瓶
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function UpdateDrift(Request = {}, Params = {}) {
  try {
    let Body = Request.body;
    let user = Request.$user;
    let { id, value, image, state } = Body;
    if (!id) {
      throw { code: 500, msg: "修改失败,id不能为空" };
    }
    // 获取Mysql连接
    const Conline = await MYSQL.promise().getConnection();
    // 更新数据
    let [UpdateResult] = await Conline.query(
      `UPDATE ${sql_drift_name} SET?
      WHERE id = ${id}
      `,
      {
        value,
        image,
        state,
      }
    );
    // 查询完毕，释放池连接回池
    await Conline.release();
    let { affectedRows } = UpdateResult
    if (affectedRows) {
      return {
        code: 0,
        msg: "修改成功",
      };
    } else {
      throw { code: 500, msg: "修改失败,记录不存在" };
    }
  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "操作失败" };
    }
  }
}
/**
 * 创建漂流瓶
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function CreateDrift(Request = {}, Params = {}) {
  try {
    let user = Request.$user;
    let Body = Request.body;
    let { value, image } = Body;
    // 获取MYSQL实例
    const Conline = await MYSQL.promise().getConnection();
    let [InsertResult] = await Conline.query(
      `
      INSERT INTO ${sql_drift_name} VALUES ?
    `,
      {
        user,
        value,
        image,
      }
    );
    // 释放连接
    await Conline.release();
    let { affectedRows } = InsertResult
    if (affectedRows) {
      return {
        code: 0,
        msg: "发布成功",
      };
    } else {
      throw {
        code: 500, msg: "发布失败,未知错误"
      }
    }
  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "发布失败" };
    }
  }
}
/**
 * 丢弃漂流瓶
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function DiscardDrift(Request = {}, Params = {}) {
  try {
    let Body = Request.body;
    let user = Request.$user;
    let { id } = Body
    if (!id) {
      throw { code: 500, msg: "丢弃失败,id不能为空" };
    }
    const Conline = await MYSQL.promise().getConnection();
    let [UpdateResult] = await Conline.query(
      `UPDATE ${sql_user_drift_log_name} SET ?
      WHERE user = ${user} AND id drift_id = ${id}
      `
      ,
      { discard: 1 }
    );
    // 查询完毕，释放池连接回池
    await Conline.release();
    let { affectedRows } = UpdateResult
    if (affectedRows) {
      return {
        code: 0,
        msg: "删除成功",
      };
    } else {
      throw { code: 500, msg: "删除失败,记录不存在" };
    }
  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "操作失败" };
    }
  }

}
/**
 * 漂流瓶列表
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function DriftList(Request = {}, Params = {}) {
  try {
    let Query = Request.query;
    let { page = 1, limit = 10 } = Query;
    page = Number(page);
    limit = Number(limit);
    let offset = (page - 1) * limit;
    // 获取Mysql连接
    const Conline = await MYSQL.promise().getConnection();
    let [list] = await Conline.query(
      `SELECT * FROM ${sql_drift_name}
    LIMIT ${offset},${limit}
    `
    );
    // 查询完毕，释放池连接回池
    await Conline.release();
    return {
      code: 0,
      msg: "操作成功",
      data: {
        page, limit,
        list,
      },
    };
  }
  catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "操作失败" };
    }
  }
}
/**
 * 漂流瓶成员列表
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function DriftMemberList(Request) {
  try {
    let Query = Request.query;
    let { id } = Query;
    if (!id) {
      throw {
        code: 500,
        msg: "缺少id字段",
      };
    }
    // 获取Mysql连接
    const Conline = await MYSQL.promise().getConnection();
    let [list] = await Conline.query(
      `SELECT * FROM ${sql_user_drift_log_name} WHERE drift_id = ${id}`
    );
    // 查询完毕，释放池连接回池
    await Conline.release();
    return {
      code: 0,
      msg: "操作成功",
      data: {
        list,
      },
    };
  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "操作失败" };
    }
  }
}
/**
 * 漂流瓶详细信息
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function DriftInfo(Request) {
  try {
    let Query = Request.query;
    let { id } = Query;
    if (!id) {
      throw {
        code: 500,
        msg: "缺少id字段",
      };
    }
    // 获取Mysql连接
    const Conline = await MYSQL.promise().getConnection();
    let [list] = await Conline.query(
      `SELECT * FROM ${sql_drift_name} WHERE id = ${id}`
    );
    if (list.length) {
      let Info = list[0]
      // 查询完毕，释放池连接回池
      await Conline.release();
      return {
        code: 0,
        msg: "操作成功",
        data: Info,
      };
    } else {
      throw {
        code: 500,
        msg: "记录不存在",
      };
    }
  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "操作失败" };
    }
  }
}
/**
 * 发布的漂流瓶列表
 * @param {*} params
 * @return {promise<{code:string,msg:string}>}
 */
async function WriteDriftList(Request) {

  try {
    let Query = Request.query;
    let user = Request.$user;
    let { page = 1, limit = 10 } = Query;
    page = Number(page);
    limit = Number(limit);
    let offset = (page - 1) * limit;
    // 获取Mysql连接
    const Conline = await MYSQL.promise().getConnection();
    let [list] = await Conline.query(
      `SELECT * FROM ${sql_drift_name}
       WHERE user = ${user}
       LIMIT ${offset},${limit}
      `
    );
    // 查询完毕，释放池连接回池
    await Conline.release();
    return {
      code: 0,
      msg: "操作成功",
      data: {
        page, limit,
        list
      }
    }
  } catch (error) {
    let { msg } = error;
    if (msg) {
      throw error;
    } else {
      throw { code: 500, msg: "操作失败" };
    }
  }

}
module.exports = {
  UpdateDrift,
  WriteDriftList,
  GetDriftObserver,
  DiscardDrift,
  DeleteDrift,
  CreateDrift,
  DriftList,
  DriftMemberList,
  DriftInfo,
};
